﻿(function () {

    window.crucible = window.crucible || {};
    var crucible = window.crucible;
    
    crucible.AssertionForm = function () {

        var self = this;

        this.wrapper = $("#argumentEditor");
        
        this.range = null;

        
        //var dirtyStructure;

        //crucible.treeMakerViewModel.focusedNode.subscribe(function (oldval) {
        //    if (oldval && oldval.IsEditing()) {
        //        if (self.typeSubscription) {
        //            self.typeSubscription.dispose();
        //        }
        //        oldval.IsEditing(false);
        //        dirtyStructure = true;
        //    }
        //}, this, "beforeChange");


        //crucible.treeMakerViewModel.focusedNode.subscribe(function (surrogateNode) {
        //    if (surrogateNode.IsDraft()) {
        //        if (!surrogateNode.Body()) {
        //            crucible.datacontext.hydrateNode(surrogateNode, function() {
        //                self.markdownEditor.refreshPreview();
        //            });
        //        }
        //        if (!self.markdownEditor) {
        //            self.init();
        //            self.initEditor();
        //        }
        //        surrogateNode.IsEditing(true);
        //        self.surrogateNode = surrogateNode;
        //        self.typeSubscription = self.surrogateNode.Type.subscribe(function() {
        //            self.markdownEditor.refreshPreview();
        //            self.canvas.draw();
        //        });
        //        self.markdownEditor.refreshPreview();
        //        self.canvas.draw();
        //        dirtyStructure = false;
        //    }

        //    if (dirtyStructure) {
        //        self.canvas.draw();
        //        dirtyStructure = false;
        //    }
        //});

        this.canvas = new crucible.ArgumentCanvas();
        

    };

    crucible.AssertionForm.prototype = function () {

        var init = function() {

            //this.titleBox = $("#Title");
            var self = this;
            this.bodyBox = $("#wmd-input");
            this.publishBtn = $("#publish");
            this.draftBtn = $("#draft");
            this.findBox = $("#quick");
            this.sourceBox = $("#Source");
            this.titlePreview = $("#title-preview");            
            

            

            //$("#createTypes").buttonset();

            var bodyarea = this.bodyBox;
            var self = this;
            var sourceBox = this.sourceBox;

            //this.draftBtn.click(function() {
            //    saveDraft(self);
            //});

            initEditor.call(this);

            bodyarea.keydown(function(event) {
                if (event.keyCode === 32 && event.ctrlKey) {
                    triggerSearch(self, event);
                }
            });


            //this.titleBox.keyup(function(event) {
            //    self.titlePreview.text(self.titleBox.val());
            //});

            function clickFix(target) {
                var rad = $("#" + target.attr("for"));
                rad[0].checked = true;
                rad.button("refresh");
                rad.change();
            }


            this.autocomplete = this.findBox.autocomplete({
                source: function(request, response) {
                    if (request.term.length > 1) {
                        typeMask = parseInt('0011', 2); // look for assertions or interpretations
                        crucible.datacontext.quickFind(luceneConvert(request.term), 10, typeMask, function(data) {
                            var mappedData = $.map(data,
                                    function (item) {
                                        if (item.Id === self.surrogateNode.Id) {
                                            return null;
                                        }

                                        return {
                                            label: item.Title,
                                            value: item.Title,
                                            id: item.Id
                                        };
                                    });

                            mappedData.push({ label: "<Create new>", value: request.term, id: 0 });

                            response(mappedData);
                        });

                    } else {
                        response([{ label: "<Create new>", value: "Untitled", id: 0 }]);
                    }
                },
                minLength: 2,
                autoFocus: true,
                select: quickFindSelected
            });


            this.sourceBox.autocomplete({
                source: function(request, response) {
                    if (request.term.length > 1) {
                        var typeMask = parseInt('0100', 2); // look for a source, assuming this is an interpretation
                        if (self.surrogateNode.Type() == crucible.NodeType.source) {
                            typeMask = parseInt('1000', 2); // look for an originator since it's a source.
                        }
                        crucible.datacontext.quickFind(luceneConvert(request.term), 10, typeMask, function(data) {
                            var mappedData = $.map(data,
                                    function (item) {
                                        return {
                                            label: item.Title,
                                            value: item.Title,
                                            id: item.Id
                                        };
                                    });

                            mappedData.push({ label: "<Create new>", value: request.term, id: 0 });

                            response(mappedData);
                        });
                        
                    } else {
                        response([{ label: "<Create new>", value: "Untitled", id: 0 }]);
                    }
                },
                minLength: 2,
                autoFocus: true,
                select: sourceSelected
            });

            function sourceSelected(event, ui) {
                var source;

                if (ui.item.id === 0) {
                    //showSourceForm(function(id, title) {
                    //    sourceBox.val("" + id + " - " + title);
                    //    event.preventDefault();add
                    //});
                    var nt = crucible.NodeType.source;
                    if (self.surrogateNode.Type() == crucible.NodeType.source) {
                        nt = crucible.NodeType.originator;
                    } else {
                        self.canvas.suppressDraw = true;
                        self.surrogateNode.Type(crucible.NodeType.interpretation);
                        self.canvas.suppressDraw = false;
                    }

                    crucible.datacontext.saveStub(self.sourceBox.val(), "", nt, function (stub) {
                        //new crucible.datacontext.Node(stub)
                        source = crucible.nodeManager.addSourceStub(stub, self.surrogateNode);
                        self.surrogateNode.Source(source);
                        self.saveDraft();
                    });
                } else {
                    if (self.surrogateNode.Type() != crucible.NodeType.source) {
                        self.canvas.suppressDraw = true;
                        self.surrogateNode.Type(crucible.NodeType.interpretation);
                        self.canvas.suppressDraw = false;
                    }
                    source = crucible.nodeManager.addSourceStub({ Id: ui.item.id, Title: ui.item.value }, self.surrogateNode); // this makes a cache entry and sets the source on the original
                    self.surrogateNode.Source(source); // this sets the source on the surrogate
                    self.saveDraft();
                }
            }

            //function showSourceForm(callback) {
            //    callback(0, "Not implemented");
            //}

            function quickFindSelected(event, ui) {
                
                self.canvas.suppressDraw = true;
                self.surrogateNode.Type(crucible.NodeType.assertion);
                self.canvas.suppressDraw = false;
                
                if (ui.item.id === 0) {
                    crucible.datacontext.saveStub(ui.item.value, "", crucible.NodeType.assertion, function(stub) {
                        addChildAssertion(stub.Id, stub.Title);
                    });
                } else {

                    addChildAssertion(ui.item.id, ui.item.label);
                    event.preventDefault();
                }
            }

            function addChildAssertion(id, label) {
                bodyarea.focus();
                if (!self.range) {
                    self.range = { start: 0, end: 0 };
                }
                bodyarea.setSelection(self.range.start, self.range.end);
                bodyarea.replaceSelectedText("{{[" + id + "]" + label + "}}");
                var selStart = self.range.start + id.toString().length + 4;
                bodyarea.setSelection(selStart, selStart + label.length);
                self.markdownEditor.refreshPreview();
                hideQuick(self);
                self.range = null;

                bodyarea.trigger("change");

                self.saveDraft(self.surrogateNode);
            }
            
            function escapeOut(event) {
                if (event.keyCode === 27 || event.keyCode === 13) {
                    setTimeout(function () { // timeout to make sure this executes AFTER the quickfind select event is processed.
                        hideQuick(self);
                        bodyarea.focus();
                        //self.range = null;
                    });
                    event.preventDefault();
                }
            }

            this.findBox.keydown(escapeOut);

            this.findBox.blur(function(event) {
                hideQuick(self);
            });
            
            this.sourceBox.keydown(escapeOut);

            this.sourceBox.blur(function (event) {
                hideQuick(self);
            });
            


            hideQuick(this);
            
            this.canvas.init();

            this.initialized = true;

        },
            initEditor = function() {

                var self = this;
                var converter = Markdown.getSanitizingConverter();
                converter.hooks.chain("postConversion", function(text) {
                    var surrogateNode = self.surrogateNode;
                    var finder = /(\{\{\[([0-9]+)\]([^}]+)\}\})/g;

                    if (surrogateNode && surrogateNode.Type() && surrogateNode.Type() != crucible.NodeType.assertion) {
                        return text.replace(finder, '<span style="text-decoration:line-through;color:red">$1</span>');
                    }
                    
                    var fixed = text.replace(finder, '<a href="#" class="assertionLink" data-id="$2">$3</a>');
                    return fixed;
                });

                this.markdownEditor = new Markdown.Editor(converter);
                this.markdownEditor.run();

                //$("#addRoot")
                //    .appendTo($("#wmd-button-row"))
                //    .click(function(e) {
                //        triggerSearch(self, e);
                //    });
            },

            saveDraft = function (node) {
                var self = this;

                node = node || this.surrogateNode;

                crucible.datacontext.saveDraft(node, function (data) {
                    //for (var i = 0; i < node.original.Children().length; i++) {
                    //    node.original.Children()[i].parent = null;
                    //}
                    //node.original.Children.removeAll();
                    crucible.nodeManager.integrateTreeData(data.nodes, data.edges, data.root);
                    self.canvas.draw();
                });
            },
            
            publish = function (node, successCallback) {
                var self = this;
                crucible.datacontext.publish(node,
                function (data) {
                    
                    crucible.nodeManager.integrateTreeData(data.nodes, data.edges, data.root);
                    crucible.treeMakerViewModel.focusNode(node.original, true);
                },
                function(errorResponse) {
                    if (errorResponse.publishProblems) {
                        for (var i = 0; i < errorResponse.publishProblems.length; i++) {
                            crucible.raiseError(errorResponse.publishProblems[i].Message, true);
                        }
                    }
                });
            },

            triggerSearch = function(self, event) {
                var bodyarea = self.bodyBox;
                event.preventDefault();
                self.range = bodyarea.getSelection();
                if (self.range.start === self.range.end) {
                    var preceding = bodyarea.val().substring(0, self.range.start);
                    if (preceding) {
                        var lastSpace = preceding.lastIndexOf(' ');
                        if (lastSpace < self.range.start - 1) {
                            bodyarea.setSelection(lastSpace + 1, self.range.start);
                            self.findBox.val(preceding.substring(lastSpace + 1, self.range.start));
                            self.range = bodyarea.getSelection();
                        }
                    }
                } else {
                    self.findBox.val(self.range.text);
                }
                self.findBox.show();
                self.findBox.focus(1);
                self.findBox.autocomplete('search');
            },
            
            triggerSourceSearch = function (self, event) {
                self.sourceBox.show();
                self.sourceBox.focus(1);
            },
            
            startEditing = function(surrogateNode) {

                var self = this;

                this.id = surrogateNode.id;
                this.surrogateNode = surrogateNode;
                

                self.typeSubscription = surrogateNode.Type.subscribe(function () {
                    //self.canvas.draw();
                    self.markdownEditor.refreshPreview();
                });

                if (!surrogateNode.hydrated) {
                    crucible.datacontext.hydrateNode(surrogateNode, function () {
                        //surrogateNode.original.decorateSurrogate(surrogateNode);
                        self.markdownEditor.refreshPreview();
                    });
                }
                
                surrogateNode.original.el.find(".wmd-holder").append($("#wmd-preview"));
                
                //$("#wmd-input").val(surrogateNode.Body());
                //surrogateNode.original.colspan = 2;
                //surrogateNode.original.rowspan = 4;

                //this.bodyBox.val(surrogateNode.body || '');

                //var radio = $("#radioAssertion");
                //if (surrogateNode.Type()) {
                //    if (surrogateNode.Type() == crucible.NodeType.interpretation) {
                //        radio = $("#radioInterpretation");
                //    } else if (surrogateNode.Type() == crucible.NodeType.axiom) {
                //        radio = $("#radioAxiom");
                //    }
                //}
                //radio[0].checked = true;
                //radio.button("refresh");
                //radio.change();


                //if (surrogateNode.assertion) {
                //    //this.titleBox.val(surrogateNode.assertion.Title);
                //    this.bodyBox.val(surrogateNode.assertion.Body);
                //    this.titlePreview.text(surrogateNode.assertion.Title);
                //}

                this.markdownEditor.refreshPreview();
            },
            finishEditing = function () {
                var surrogateNode = this.surrogateNode;
                
                if (this.typeSubscription) {
                    this.typeSubscription.dispose();
                }
                
                //surrogateNode.IsEditing(false);
                
                //if (surrogateNode.original) {
                //    surrogateNode.original.absorbSurrogate(surrogateNode); // gather final values from the editing surrogate into the old surrogateNode
                //}

                $("#hiddenDiv").append($("#wmd-preview"));
                //surrogateNode.original.el.removeClass("focusedNode", 200);
                //surrogateNode.original.colspan = 1;
                //surrogateNode.original.rowspan = 1;
                
            },
            hideQuick = function(self) {
                setTimeout(function() {
                    self.findBox.val("");
                    self.findBox.hide();
                    self.sourceBox.val("");
                    self.sourceBox.hide();
                });
            };
            
        //saveStub = function (title, body, callback) {

        //    $.ajax({
        //        url: "/Assertion/SaveDraft",
        //        type: "POST",
        //        data: {
        //            Id: 0,
        //            Title: title || "Untitled",
        //            Body: body || "This assertion is a stub.",
        //            IsDraft: true,
        //            sendTree: false
        //        },
        //        success: function (stub) {
                    
        //            var props = {}; // Log event to mixpanel
        //            props[crucible.mixprops.nodeId] = stub.Id;
        //            props[crucible.mixprops.nodeTitle] = stub.Title;
        //            mixpanel.track(crucible.mixevents.saveStub, props);
                    
        //            callback(stub);
        //        }
        //    });

        //},

        //saveDraft = function (self) {
        //    var body = self.bodyBox.val();
        //    var title = self.titleBox.val();

        //    $.ajax({
        //        url: "/Assertion/SaveDraft",
        //        type: "POST",
        //        data: {
        //            Id: self.id,
        //            Title: title || "Untitled",
        //            Body: body,
        //            Type: self.surrogateNode.type || 1,
        //            IsDraft: true,
        //            sendTree: true
        //        },
        //        success: function (treeData) {
        //            self.id = treeData.root.Id;

        //            self.wrapper.trigger("treereceived", treeData);

        //            $.pnotify({ title: "Success", text: "Draft saved.", type: 'success' });
                    
        //            var props = {}; // Log event to mixpanel
        //            props[crucible.mixprops.nodeId] = treeData.root.Id;
        //            props[crucible.mixprops.nodeTitle] = treeData.root.Title;
        //            mixpanel.track(crucible.mixevents.saveDraft, props);
        //        }
        //    });

        //};

        return {
            init: init,
            startEditing: startEditing,
            finishEditing: finishEditing,
            saveDraft: saveDraft,
            publish: publish,
            triggerSearch: triggerSearch,
            triggerSourceSearch: triggerSourceSearch
        };

    }();

    function luceneConvert(queryText) {
        queryText = queryText.trim();
        if (/^[^\s"]*[^*"]$/.test(queryText)) {
            queryText += "*";
        }
        return queryText;
    }


}());